eMotelPro — Phần mềm quản lý nhà trọ, phòng trọ viết bằng PHP thuần
Tải về → giải nén vào `htdocs` → import file SQL → sửa 4 dòng cấu hình → **chạy được ngay**.
Không Composer, không Node.js, không bước biên dịch, không cần VPS.
Sản phẩm phục vụ tốt cả hai nhu cầu:
- **Sinh viên làm đồ án tốt nghiệp** — có sẵn báo cáo 118 trang, slide thuyết trình, dữ liệu mẫu
đầy đủ để demo trước hội đồng mà không phải ngồi nhập liệu.
- **Chủ nhà trọ dùng thật** — quy mô 5 đến 100 phòng, thao tác được trên điện thoại, mua đứt một
lần, không thuê bao hằng tháng.
1. Bạn nhận được những gì
| Thành phần | Chi tiết |
|---|---|
| **Mã nguồn đầy đủ** | 178 file PHP, hơn 20.000 dòng, không mã hóa, không rút gọn |
| **Cơ sở dữ liệu** | 2 file SQL: bản có dữ liệu mẫu và bản trống (chỉ danh mục nền) |
| **Báo cáo đồ án** | Word + PDF, **118 trang** — đầy đủ chương mục, sơ đồ UML, ma trận truy vết yêu cầu |
| **Slide thuyết trình** | PowerPoint, dùng bảo vệ được ngay |
| **Video hướng dẫn** | 3 video (cài đặt · sử dụng · giới thiệu) + 1 video trọn bộ **11 phút**, có phụ đề tiếng Việt |
| **Hướng dẫn cài đặt** | 5 bước, kèm cách xử lý các lỗi thường gặp |
| **Danh sách test case** | Dùng làm chương kiểm thử trong báo cáo |
| **Tài liệu thiết kế CSDL** | Mô tả từng bảng, từng quan hệ khóa ngoại |
### Dữ liệu mẫu có sẵn — cắm vào là demo được
2 cơ sở · **60 phòng** · 52 khách thuê · **52 hợp đồng** đang hiệu lực · 3 kỳ điện nước đã ghi ·
**156 hóa đơn** đủ mọi trạng thái (đã thu, còn nợ, quá hạn) · phiếu thu · thu chi · tài sản · sự cố.
Không phải ngồi nhập liệu trước khi demo. Mở lên là biểu đồ có số, công nợ có dòng, dashboard có
việc cần xử lý.
2. Chức năng khu quản trị
🏢 Cơ sở, tòa nhà, tầng, phòng
- Quản lý nhiều cơ sở, mỗi cơ sở nhiều tòa nhà, mỗi tòa nhiều tầng
- **Sơ đồ phòng trực quan** — mỗi ô một phòng, màu theo trạng thái, nhìn một lần biết cả khu
- 6 trạng thái phòng: trống · đang thuê · đã đặt · sắp trả · đang sửa · ngừng sử dụng
- Gán dịch vụ và tài sản cho từng phòng, tải ảnh phòng
👥 Khách thuê
- Hồ sơ đầy đủ: họ tên, ngày sinh, số điện thoại, căn cước, địa chỉ thường trú
- Tải lên bản chụp giấy tờ, lưu an toàn — **chỉ tải về được qua trang có kiểm quyền**
- Lịch sử cư trú, danh sách thành viên cùng phòng
📄 Hợp đồng và tiền cọc
- Tạo hợp đồng: chọn phòng trống, khách đại diện, thời hạn, giá thuê, tiền cọc
- Lưu hợp đồng làm **đồng thời 5 việc**: sinh mã hợp đồng · thêm thành viên · tạo sổ tiền cọc ·
chuyển phòng sang "đang thuê" · mở lịch sử cư trú
- **Sổ biến động tiền cọc** — mỗi lần nhận, bổ sung, khấu trừ, hoàn cọc là một dòng riêng, có
căn cứ đối chiếu khi tranh chấp
- In hợp đồng, biên bản bàn giao, biên bản thanh lý
- Cảnh báo hợp đồng sắp hết hạn ngay trên dashboard
⚡ Ghi điện nước
- Ghi chỉ số theo kỳ, **tự điền sẵn chỉ số cũ của kỳ trước**
- Ghi hàng loạt cho cả cơ sở trong một màn hình
- **Từ chối chỉ số mới nhỏ hơn chỉ số cũ** — chặn sai sót ngay lúc nhập
- Đơn giá cấu hình được, lưu ảnh công tơ làm bằng chứng
🧾 Hóa đơn
- Lập từng hóa đơn hoặc **lập hàng loạt cho toàn bộ hợp đồng của một cơ sở trong một thao tác**
- Cấu trúc dòng hóa đơn linh hoạt (`invoice_items`) — thêm khoản thu mới không phải sửa cấu trúc bảng
- 7 trạng thái: chưa gửi · đã gửi · chưa thanh toán · thanh toán một phần · đã thanh toán · quá hạn · hủy
- **Mã QR chuyển khoản VietQR** in ngay trên hóa đơn — chuẩn NAPAS 247, sinh từ số tài khoản bạn
khai trong Cài đặt, **không cần đăng ký cổng thanh toán, không tốn phí**
- In hóa đơn bằng chức năng in của trình duyệt (Ctrl+P → lưu PDF hoặc in giấy)
💰 Thu tiền và công nợ
- Thu tiền theo hợp đồng, nhiều phương thức
- **Tự phân bổ vào hóa đơn đến hạn sớm nhất trước** — đúng nguyên tắc kế toán xử lý công nợ,
người dùng không phải tự chọn trả hóa đơn nào
- Khách trả làm nhiều lần vẫn theo dõi chính xác
- Bảng công nợ: tổng cần thu · đã thu · còn nợ · quá hạn, chi tiết đến từng phòng và số ngày trễ
- **Xuất danh sách công nợ và danh sách hóa đơn ra file CSV** (mở trực tiếp bằng Excel), xuất theo
đúng bộ lọc đang xem
- In phiếu thu
🏦 Đối soát ngân hàng
- **Nhập file sao kê Excel/CSV bạn tự tải từ app ngân hàng**
- Tự khớp nội dung chuyển khoản (mã phòng + kỳ) với hóa đơn tương ứng
- Không gọi API ngân hàng, không cần hợp đồng doanh nghiệp — dùng được ngay
📊 Báo cáo và dự báo
- Doanh thu 12 tháng, chi phí, lợi nhuận ước tính, tỷ lệ lấp đầy
- Biểu đồ Chart.js, so sánh theo kỳ
- **Dự báo doanh thu tháng tới bằng hồi quy tuyến tính chạy ngay trên máy chủ của bạn** —
không gửi dữ liệu ra ngoài, không gọi dịch vụ AI nào
- Báo cáo hỗ trợ kê khai thuế theo từng cơ sở
🔧 Vận hành hằng ngày
| Module | Nội dung |
|---|---|
| Thu chi / sổ quỹ | Ghi các khoản thu chi ngoài tiền phòng, phân loại theo danh mục |
| Tài sản | Danh mục tài sản, gán vào phòng, biên bản bàn giao |
| Sửa chữa | Tiếp nhận sự cố, theo dõi trạng thái xử lý, ghi nhật ký |
| Dịch vụ | Internet, rác, gửi xe… gán theo phòng, tự cộng vào hóa đơn |
| Đặt phòng | Giữ chỗ trước khi ký hợp đồng |
| Thanh lý hợp đồng | Xem trước số tiền hoàn, khấu trừ tự động, sinh biên bản |
| Thông báo | Gửi thông báo trong hệ thống và qua email (SMTP bạn tự khai) |
| Sao lưu / phục hồi | **Sao lưu CSDL bằng một nút bấm trong giao diện**, không cần biết `mysqldump` |
| Nhật ký hoạt động | Ghi lại ai làm gì, lúc nào, giá trị trước và sau khi sửa |
| Tìm kiếm tổng hợp | Một ô tìm kiếm cho phòng, khách, hợp đồng, hóa đơn |
3. Cổng thông tin khách thuê
Khách thuê **đăng nhập bằng số điện thoại** vào cổng riêng, giao diện tối giản dùng tốt trên điện thoại:
- Xem hợp đồng, giá thuê, công nợ hiện tại của chính mình
- Xem hóa đơn từng kỳ, xem chi tiết từng khoản
- Xem chỉ số điện nước đã ghi
- **Gửi báo sự cố** kèm ảnh, theo dõi trạng thái xử lý
- Nhận thông báo từ chủ trọ
Chủ trọ giảm hẳn số cuộc gọi hỏi tiền phòng mỗi cuối tháng.
4. Điểm kỹ thuật — phần hội đồng hỏi nhiều nhất
Kiến trúc 3 tầng đúng chuẩn
Giao diện (admin/, portal/) → Nghiệp vụ (includes/services/) → Dữ liệu (includes/repositories/)
**Không một công thức tính tiền nào nằm trong trang hiển thị.** Toàn bộ đặt trong 10 lớp Service:
`BillingService`, `DienNuocService`, `ThanhToanService`, `CongNoService`, `BaoCaoService`,
`DoiSoatNganHangService`, `ThanhLyHopDongService`, `PhanTichService`, `ThongBaoService`, `SaoLuuService`.
Đây chính là mô hình bạn vẽ ở Chương 2 báo cáo — code khớp đúng sơ đồ, không phải giải thích vòng vo.
### Mỗi file mở đầu bằng chú thích tiếng Việt
```php
/**
* File: admin/phong/index.php
* Module: Quản lý phòng
* Mô tả: Danh sách phòng có lọc theo cơ sở/trạng thái/từ khóa, phân trang.
* Tham số nhận vào: GET property_id, status, q, trang, sort, huong.
* Quyền yêu cầu: rooms.view
*/
```
Mở file nào cũng biết ngay nó làm gì. Không phải đọc mò.
Công thức nghiệp vụ ghi thẳng trong code
| Nghiệp vụ | Công thức |
|---|---|
| Tiền điện / nước | `Tiêu thụ = Chỉ số mới − Chỉ số cũ` → `Thành tiền = Tiêu thụ × Đơn giá` |
| Tổng hóa đơn | `Tiền phòng + Tiền điện + Tiền nước + Tổng dịch vụ đang áp dụng` |
| Phân bổ thanh toán | Trả vào hóa đơn **đến hạn sớm nhất** trước, dư mới chuyển sang hóa đơn kế tiếp |
| Khấu trừ cọc khi thanh lý | `Công nợ cũ → Phí phát sinh → Phần còn dư hoàn lại khách` (đúng thứ tự này) |
Công thức trong code **khớp từng chữ** với công thức trong báo cáo Chương 3.
Cơ sở dữ liệu
- **48 bảng**, đặt tên tiếng Anh `snake_case`, khóa ngoại `<bảng số ít>_id` — dễ đọc, dễ vẽ ERD
- Xóa mềm (`deleted_at`) ở phòng, khách thuê, hợp đồng — không mất dữ liệu lịch sử
- `utf8mb4_unicode_ci`, InnoDB — **chạy được trên cả MySQL 8 và MariaDB 10.4**
- Không dùng CHECK constraint, không cột generated, không CTE đệ quy → import không kén phiên bản
Phân quyền thật, không phải ẩn nút
- **63 quyền** chia theo 19 nhóm module
- **3 vai trò sẵn**: Chủ nhà trọ (63 quyền) · Quản lý (53 quyền) · Nhân viên (19 quyền)
- **Kiểm quyền ở cả hai tầng**: chặn ngay đầu trang *và* ẩn nút trên giao diện.
Chỉ ẩn nút mà không chặn trang là lỗ hổng — sản phẩm này không mắc lỗi đó.
- **Phạm vi dữ liệu theo cơ sở**: quản lý chỉ thấy phòng, khách, hóa đơn của cơ sở được giao
An toàn
| Biện pháp | Cách làm |
|---|---|
| Chống SQL Injection | 100% truy vấn dùng prepared statement, không nối chuỗi vào SQL |
| Chống CSRF | Mọi form POST có token, mọi file xử lý POST kiểm tra token |
| Mật khẩu | `password_hash()` BCRYPT, không bao giờ truy vấn cột mật khẩu ra giao diện |
| Chống dò mật khẩu | Khóa tạm 15 phút sau 5 lần đăng nhập sai liên tiếp |
| Chống XSS | Escape mọi biến in ra HTML |
| Chống sắp xếp/lọc độc hại | Cột sắp xếp chỉ nhận giá trị trong danh sách trắng |
| File tải lên | Kiểm phần mở rộng, đổi tên ngẫu nhiên, giới hạn dung lượng, **chỉ phục vụ qua trang có kiểm quyền** |
Chạy sạch, không warning
Viết theo chuẩn chạy sạch trên **PHP 8.0 → 8.3, không một warning** — không dùng cú pháp đã bỏ,
không dùng biến chưa khởi tạo. Đây là điểm yếu chí tử của nhiều source code cùng phân khúc: mở lên
đầy dòng `Warning: Undefined variable` ngay trước mặt hội đồng.
Gói mã nguồn còn kèm công cụ tự kiểm tra:
```bash
php tools/kiem-tra.php
```
Kiểm kết nối CSDL, phân quyền đã nạp đúng chưa, và mở thử các trang chính xem có lỗi PHP không.
### Giao diện
- Bootstrap 5.3, **responsive** — chủ trọ ghi điện nước, thu tiền, xem công nợ ngay trên điện thoại
- Sidebar thu gọn được, có chế độ tối
- **Toàn bộ thư viện để local trong `assets/vendor/`** (Bootstrap, Chart.js, FontAwesome, PHPMailer) —
**không dùng CDN**, máy không có Internet vẫn chạy đủ giao diện
- Tùy chỉnh thương hiệu: đổi tên, biểu tượng, màu logo ngay trong phần Cài đặt
5. Yêu cầu hệ thống
| Thành phần | Yêu cầu |
|---|---|
| PHP | **8.0 trở lên** (khuyên dùng 8.1–8.3) |
| CSDL | MySQL 8.0 hoặc MariaDB 10.4 trở lên |
| Web server | Apache (khuyên dùng) hoặc Nginx |
| Extension PHP | `pdo_mysql`, `gd`, `curl`, `mbstring`, `zip` — đều có sẵn trong XAMPP và hosting phổ thông |
| Dung lượng | Khoảng 200 MB |
Chạy tốt trên **XAMPP** (Windows/macOS/Linux) và **hosting cPanel/DirectAdmin** thông thường.
**Không cần VPS, không cần quyền root, không cần Composer, không cần Node.js.**
6. Vì sao chọn PHP thuần thay vì framework
Hai sản phẩm cùng ngách trên sàn đều viết bằng Laravel. Với người mua làm đồ án, PHP thuần là **ưu
thế chứ không phải điểm yếu**:
- **Giải thích được từng dòng trước hội đồng.** Không phải trả lời "cái này Laravel tự làm ạ".
- **Không phụ thuộc thư viện tải từ mạng.** Không `composer install`, không lo lệch phiên bản.
- **Chạy được trên hosting rẻ nhất.** Không cần quyền chạy lệnh, không cần cấu hình đặc biệt.
- **Cấu trúc vẫn chuẩn.** Tách Service/Repository rõ ràng, muốn chuyển sang Laravel sau này thì ánh
xạ gần như 1-1, không phải viết lại từ đầu.
**Khoảng 5 phút là chạy được.** Không cần Composer, không cần Node.js, không có bước biên dịch,
không cần VPS hay quyền root.
Nếu bạn thích xem hơn đọc: trong gói có sẵn **video hướng dẫn cài đặt** quay lại toàn bộ các bước
dưới đây trên màn hình thật.
Năm extension trên **có sẵn trong XAMPP và mọi hosting phổ thông**, bạn không phải cài thêm.
Chạy tốt trên **XAMPP** (Windows / macOS / Linux) và **hosting cPanel / DirectAdmin**.
Đặt tên thư mục tùy ý. **Hệ thống tự nhận diện đường dẫn cài đặt**, chạy ở tên miền gốc hay thư mục
con đều được, không phải sửa dòng code nào.
1. Mở **phpMyAdmin** (XAMPP: `http://localhost/phpmyadmin`) hoặc trình quản trị CSDL của hosting.
2. Tạo database mới, tên tùy ý (ví dụ `emotelpro`), chọn bảng mã **`utf8mb4_unicode_ci`**.
3. Chọn database vừa tạo → thẻ **Import / Nhập** → chọn file trong gói → **Go / Thực hiện**.
| `database/emotelpro.sql` | **Muốn xem demo ngay** — kèm sẵn 2 cơ sở, 60 phòng, 52 hợp đồng, 156 hóa đơn đủ trạng thái |
| `database/emotelpro_trong.sql` | **Muốn dùng thật ngay** — chỉ có danh mục nền (vai trò, quyền, tài khoản quản trị), không dữ liệu mẫu |
> 💡 Làm đồ án thì chọn file có dữ liệu mẫu — demo trước hội đồng có ngay biểu đồ, có công nợ, có
> việc cần xử lý, không phải ngồi nhập tay hàng trăm dòng.
Mở `config/config.php` bằng trình soạn thảo bất kỳ (Notepad++, VS Code, hoặc trình sửa file của
define('DB_PASS', ''); // Mật khẩu MySQL (XAMPP mặc định: để trống)
Lưu lại. **Không cần sửa gì khác.**
*Chỉ áp dụng khi cài trên hosting Linux. Cài trên XAMPP Windows thì bỏ qua bước này.*
Thư mục này chứa ảnh giấy tờ khách thuê, ảnh công tơ, ảnh phòng.
Mở trình duyệt vào địa chỉ vừa cài — ví dụ `http://localhost/emotelpro/` hoặc `https://tenmien.com/`.
> Bấm vào tên tài khoản ở góc phải trên → **Đổi mật khẩu**.
**Xong.** Bạn đã có thể dùng toàn bộ chức năng.
Trong gói có sẵn công cụ tự kiểm tra. Mở cửa sổ dòng lệnh tại thư mục dự án và chạy:
Công cụ kiểm kết nối CSDL, phân quyền đã nạp đúng chưa, và mở thử các trang chính xem có lỗi PHP
không. **Nếu cần nhờ hỗ trợ, bạn chụp kết quả lệnh này gửi kèm là tôi biết ngay vấn đề nằm ở đâu.**
Phần mềm chạy đủ mọi nghiệp vụ chính mà không cần cấu hình gì thêm. Bốn mục dưới đây bật khi bạn cần,
| **QR chuyển khoản VietQR** | Mã BIN ngân hàng + số tài khoản | Tra mã BIN tại `vietqr.io/danh-sach-ngan-hang`. **Không cần đăng ký cổng thanh toán, không mất phí** |
| **Gửi email thông báo** | Thông tin SMTP (Gmail, mail hosting…) | Dùng PHPMailer có sẵn trong gói, không phải cài thêm |
| **Gửi SMS / Zalo OA** | Endpoint webhook + token của nhà cung cấp bạn đang dùng | Cần bạn đã có sẵn tài khoản dịch vụ hỗ trợ nhận webhook |
| **Tùy chỉnh thương hiệu** | Tên đơn vị, biểu tượng, màu logo | Đổi nhận diện toàn hệ thống, không đụng vào code |
1. **Đổi mật khẩu quản trị mặc định** (Bước 5 ở trên).
2. **Tắt chế độ gỡ lỗi.** Mở `config/config.php`, đổi:
Để ẩn chi tiết lỗi kỹ thuật khỏi người dùng cuối.
3. **Tạo tài khoản MySQL riêng có mật khẩu** thay cho `root` khi chạy trên máy chủ thật.
4. *(Tùy chọn)* Xóa thư mục `tools/` nếu không dùng tới các script dòng lệnh.
Các thư mục nhạy cảm `config/`, `database/`, `includes/`, `tools/` **đã được chặn truy cập trực
tiếp qua trình duyệt** bằng file `.htaccess` đi kèm — xóa bớt chỉ là lớp phòng thủ bổ sung.
| **Trang trắng** hoặc báo *"Lỗi kết nối cơ sở dữ liệu"* | Kiểm tra lại 4 dòng `DB_*` ở Bước 3 đã khớp database thật chưa. Kiểm tra MySQL/MariaDB đã bật chưa. |
| **Giao diện mất màu, chữ thô** | Thư mục `assets/vendor/` bị thiếu file khi giải nén. Giải nén lại toàn bộ gói, không bỏ sót thư mục nào. |
| **Đăng nhập báo sai mật khẩu** dù gõ đúng | File SQL chưa import xong, hoặc import nhầm database. Mở phpMyAdmin kiểm tra bảng `users` đã có dữ liệu chưa. |
| **Báo khóa đăng nhập 15 phút** | Cơ chế chống dò mật khẩu, khóa sau 5 lần sai liên tiếp. Chờ hết 15 phút, hoặc xóa dòng tương ứng trong bảng `login_attempts`. |
| **Trang QR báo *"Chưa cấu hình tài khoản nhận tiền"*** | Bình thường khi chưa khai ngân hàng. Vào **Cài đặt** nhập mã BIN và số tài khoản (mục 4). |
| **Apache báo lỗi cổng 80** (XAMPP) | Ứng dụng khác đang chiếm cổng 80. Tắt ứng dụng đó, hoặc đổi cổng Apache trong `httpd.conf`. |
| **Lỗi `mod_rewrite` / trang con báo 404** | Bật `mod_rewrite` trên Apache. Hosting cPanel thường đã bật sẵn. |
Không xử lý được thì cứ nhắn — **hỗ trợ đến khi bạn chạy được**, tự cài không xong thì tôi cài giúp
miễn phí.